package technique;

import fonctionnel.Fichier;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;

/**
 * Classe NoeudImpl qui implemente l'interface NoeudIntf, pour la gestion des noeuds en RMI
 * @author S Jousselin / M Quin / V Delcroix
 */

public class NoeudImpl implements NoeudIntf {
    private ArrayList<Fichier> listeFichier;
    private String repertoire;

    /**
     * Constructeur de la classe NoeudImpl
     */
    public NoeudImpl(String repertoire)
    {
        this.repertoire=repertoire;
        this.listeFichier=new ArrayList<Fichier>();
    }


    /**
     * Remplie la liste des fichiers présents pour le noeud dont l'adresse IP est passée
     * en paramètre
     * @param AdrIp String
     */
    public void getListeFichier(String AdrIp)
    {
        this.listeFichier.clear();
        File path = new File(this.repertoire + "\\" +AdrIp);
        if (path.exists())
        {
            // Récupère tous les fichiers dans un tableau
            File[] files = path.listFiles();
            for(int i=0; i < files.length; i++)
            {
                 if(files != null && files[i].isFile() == true)
                 {
                     // Insère les fichiers dans la liste
                     this.listeFichier.add(new Fichier(files[i].getName(), 0));
                 }
            }
        }
        else
        {
            System.out.println("! Répertoire non trouvé !");
        }
    }

    /**
     * Récupère le numéro de la dernière version d'un fichier dont le nom est passé en paramétre
     * @param nomFic String
     * @return numero de version
     */
    public int getVersion(String nomFic)
    {
        int version=0;
        int max = 0;
        for(Fichier fic: this.listeFichier)
        {
            // Vérifie que le fichier existe dans la liste des fichiers
            if(fic.getNom().substring(3,fic.getNom().length()).equals(nomFic))
            {
                version=Integer.parseInt(fic.getNom().substring(1,3));
                if(version>max) max = version;
            }
        }
        return max;
    }

    /**
     * Retourne la liste des versions pour un fichier donné
     * @param AdrIp String
     * @param nomFic String
     * @return la liste des fichiers
     */
    public String listeVersion(String AdrIp, String nomFic)
    {
        String liste="";
        this.getListeFichier(AdrIp);
        for(Fichier fic: this.listeFichier)
        {
            if(fic.getNom().substring(3,fic.getNom().length()).equals(nomFic))
            {
                liste=liste + fic.getNom();
                liste=liste + "\n";
            }
        }
        return liste;
    }

    /**
     * Récupère le contenu du fichier dont le nom est passé en paramètre
     * @param AdrIP String
     * @param nomFic String
     * @return contenu du fichier
     */
    public String recupVersion(String AdrIP, String nomFic)
    {
        String Retour="";
        try
        {
            // Lecture du fichier
            FileReader ficSource = new FileReader(this.repertoire+"\\"+AdrIP+"\\"+nomFic);
            BufferedReader ligneLu = new BufferedReader(ficSource);
            String ligne;
            do
            {
                    ligne = ligneLu.readLine();
                    if (ligne != null){
                            Retour+=(ligne+"\n");
                    }
            } while (ligne != null);
            ligneLu.close();
            // Envoi ligne au Noeud
            return Retour;
        }
        catch(Exception e)
        {
            System.out.println(e);
        }
        return null;
    }

    /**
     * Copie le contenu du fichier dont le nom est passé en paramètre dans le repertoire correspondant
     * @param AdrIP String
     * @param nomFic String
     * @param contenu String
     */
    public void dupliquer(String AdrIP, String nomFic, String contenu)
    {
        // crée un répertoire sur le noeud de confiance correspondant au noeud
        File rep = new File(this.repertoire + "\\" +AdrIP);
        if(!rep.exists())
        {
            rep.mkdirs();
        }
        else
        {
            this.getListeFichier(AdrIP);
        }

        int max=getVersion(nomFic);
        max++;
        if(max<=9)
        {
            nomFic="V0" + max+nomFic;
        }
        else
        {
            nomFic="V" + max+nomFic;
        }

        try
        {
            String lecture="";
            FileWriter f = new FileWriter(this.repertoire + "\\" + AdrIP + "\\" + nomFic, false);
            BufferedWriter sortie = new BufferedWriter(f);
            lecture=contenu.replaceAll("\n", "\r\n");
            sortie.write(lecture);
            sortie.flush();
            sortie.close();
            f.close();
        }
	catch(Exception E)
        {
            System.out.println("Error"+E);
        }
    }

    /**
     * Récupère la dernière version du fichier dont le nom est passé en paramètre
     * @param AdrIP String
     * @param nomFic String
     * @return le contenu du fichier
     */
    public String recup(String AdrIP, String nomFic)
    {
        this.getListeFichier(AdrIP);
        int version = this.getVersion(nomFic);
        if(version!=0)
        {
            if(version<=9)
            {
                nomFic="V0" + version+nomFic;
            }
            else
            {
                nomFic="V" + version+nomFic;
            }

            String Retour="";
            try
            {
                // Lecture du fichier
                FileReader ficSource = new FileReader(this.repertoire+"\\"+AdrIP+"\\"+nomFic);
                BufferedReader ligneLu = new BufferedReader(ficSource);
                String ligne;
                do
                {
                        ligne = ligneLu.readLine();
                        if (ligne != null){
                                Retour+=(ligne+"\n");
                        }
                } while (ligne != null);
                ligneLu.close();
                // Envoi ligne au Noeud
                return Retour;
            }
            catch(Exception e)
            {
                System.out.println(e);
            }
        }
        return null;
    }


    /**
     * Supprime toutes les versions d'un fichier passé en paramètre
     * @param adrIp String
     * @param nomFic String
     */
    public void supprimerFichier(String adrIp, String nomFic)
    {
        File path = new File(this.repertoire + "\\" +adrIp);
        
        if (path.exists())
        {
            // Récupère tous les fichiers dans un tableau
            File[] fic = path.listFiles();
            for(int i=0; i < fic.length; i++)
            {
                if(fic[i].getName().substring(3,fic[i].getName().length()).equals(nomFic))
                {
                    fic[i].delete();
                }
            } 
         }
    }

}
